package net.kangyee.eventmanager;

import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.plugin.java.JavaPlugin;

import com.google.common.io.CharStreams;

import net.kangyee.eventmanager.commands.CommandManager;
import net.kangyee.eventmanager.listeners.ListenPlayerJoin;
import net.kangyee.eventmanager.util.ConfigManager;
import net.kangyee.eventmanager.util.MessageManager;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.net.ssl.HttpsURLConnection;
import sun.net.www.protocol.https.Handler;

/*
 * 呃..?
 */

public class EventManager extends JavaPlugin implements Listener {

	//玩家信息存储位置
	//1:Player对象 2:冻结状态
	public Map<Player, Boolean> regPlayers = new ConcurrentHashMap<Player, Boolean>();

	private boolean eventRegState; // 活动报名状态
	private boolean eventState; // 活动状态
	private String eventName; // 活动名称

	private static String pluginfolder;

	private ConfigManager config;
	
	private String[] newVerInfo;

	public void onEnable() {

		//获取插件文件夹路径
		//使用 File.separator 可以防止在其他环境(如Linux)下出现无法获取路径的情况
		pluginfolder = getDataFolder().getPath() + File.separator;

		config = new ConfigManager(this);
		this.init();
		
		getLogger().info("插件已加载,当前版本:" + getDescription().getVersion());
		//新版本检查
		try {
			//在没有对使用的SSL实现类进行配置的情况下，在程序中如果正常使用 java.net.URL 的不带 URLStreamHandler 参数的构造方法 new 一个URL对象的话
			//url.openConnection() 默认是返回 sun.net.www.protocol.http.HttpURLConnection 类型对象。
			//所以需要带上一个 URLStreamHandler 参数，否则将出现无法强制转换的异常
			//来源：http://www.xuebuyuan.com/2097844.html
			URL url = new URL(null, "https://git.oschina.net/KangYee/eventmanager/raw/master/Version", new Handler());
			HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
			newVerInfo = CharStreams.toString(new InputStreamReader(https.getInputStream())).split(";");
			//newVerInfo[0] = newVersion
			//newVerInfo[1] = newVerDownloadAddress
			if(!newVerInfo[0].equalsIgnoreCase(this.getDescription().getVersion())) {
				getLogger().info("发现新版本:" + newVerInfo[0] + ",请前往MCBBS插件发布页下载最新版更新噢");
				getLogger().info("或通过这个网址下载:" + newVerInfo[1]);
				getServer().getPluginManager().registerEvents(new ListenPlayerJoin(newVerInfo), this);
			}
		} catch (IOException e) {
			getLogger().info("获取最新版本时发生意外");
			e.printStackTrace();
		}

		//统计信息
		if (config.configMetrics) new Metrics(this);
		//有人知道怎么卸载已经注册的事件吗
		//因设计原因暂时放弃
		//if (config.configQuitEventOnLeave) getServer().getPluginManager().registerEvents(new ListenPlayerQuit(this, config), this);
		//if (config.configQuitEventOnDeath) getServer().getPluginManager().registerEvents(new ListenPlayerDeath(this, config), this);

		CommandManager commandManager = new CommandManager(this, config);
		commandManager.init();

		getCommand("eventmanager").setExecutor(commandManager);

		getServer().getPluginManager().registerEvents(this, this);
	}

	public void onDisable() {
		this.resetPlugin();
		getLogger().info("插件已卸载");
	}

	// 获取插件路径
	public static String getPluginFolder() {
		return pluginfolder;
	}
	
	// 初始化
	//单独写一个方法是为了配合 reload 指令使用
	public void init(){
		config.load();
		// 设置消息前缀
		MessageManager.setMessagePrefix(config.messagePrefix, config.messageAdminPrefix);
	}

	// 重置插件设定
	public void resetPlugin() {
		setEventState(false);
		setEventRegState(false);
		setEventName("");
		regPlayers.clear();
	}
	
	// 重置玩家报名状态
	public void resetPlayer(Player player) {
		regPlayers.remove(player.getPlayer());
	}

	// 设置活动名称
	public void setEventName(String name) {
		eventName = name;
	}

	// 获取活动名称
	public String getEventName() {
		return eventName;
	}

	// 设置活动报名状态
	public void setEventRegState(boolean state) {
		eventRegState = state;
	}

	// 获取活动报名状态
	public boolean getEventRegState() {
		return eventRegState;
	}

	// 设置活动状态
	public void setEventState(boolean state) {
		eventState = state;
	}

	// 获取活动状态
	public boolean getEventState() {
		return eventState;
	}

	// 获取活动状态
	public String getEventState(boolean state) {
		return state ? "开启" : "关闭";
	}

	// 获取活动报名人数
	public int getRegCount() {
		return regPlayers.size();
	}

	// 修改移动状态
	public void setMoveState(Player player, boolean state) {
		regPlayers.put(player, state);
	}
	
	// 玩家状态验证
	public boolean playerStateChecker(Player sender, String player){
		Player p = Bukkit.getPlayer(player);
		if(p == null){
			MessageManager.sendNormalMessage(sender, "&c该玩家不在线");
			return false;
		}
		if(!regPlayers.containsKey(p)){
			MessageManager.sendNormalMessage(sender, "&c该玩家未报名参加活动");
			return false;
		}
		return true;
	}
	
	@EventHandler(priority = EventPriority.NORMAL)
    public void onPlayerQuit(PlayerQuitEvent e) {
		if (!config.configQuitEventOnLeave) return;
		Player p = e.getPlayer();
		if (regPlayers.containsKey(p)) {
			resetPlayer(p);
			MessageManager.sendNormalMessageToAll(config.messageQuit.replaceAll("%name%", p.getDisplayName())
					.replaceAll("%event%", getEventName())
					.replaceAll("%count%", String.valueOf(getRegCount())));
		}
	}
	
	@EventHandler(priority = EventPriority.NORMAL)
	public void onPlayerDeath(PlayerDeathEvent e) {
		if (!config.configQuitEventOnDeath) return;
		Player p = e.getEntity();
		if (regPlayers.containsKey(p)) {
			resetPlayer(p);
			MessageManager.sendNormalMessageToAll(config.messageQuit.replaceAll("%name%", p.getDisplayName())
					.replaceAll("%event%", getEventName())
					.replaceAll("%count%", String.valueOf(getRegCount())));
		}
	}

	@EventHandler(priority = EventPriority.HIGHEST)
	public void onPlayerMove(PlayerMoveEvent e) {
		if (regPlayers.containsKey(e.getPlayer()) && regPlayers.get(e.getPlayer())) {
			double px = e.getPlayer().getLocation().getX();
			double py = e.getPlayer().getLocation().getY();
			double pz = e.getPlayer().getLocation().getZ();
			World pworld = e.getPlayer().getLocation().getWorld();
			Location loc = new Location(pworld, px, py, pz);
			e.getPlayer().teleport(loc);
		}
	}

	@EventHandler(priority = EventPriority.NORMAL)
	public void onPlayerChat(AsyncPlayerChatEvent e) {
		if (getEventState() && e.getMessage().toLowerCase().contains("join")) {
			Player p = e.getPlayer();
			if (!p.hasPermission("eventmanager.player.join")){
				MessageManager.sendNoPermMessage(p, "eventmanager.player.join");
				return;
			}
			if (!getEventRegState() && !p.hasPermission("eventmanager.admin.toggle")) {
				MessageManager.sendNormalMessage(p, "&c目前服务器暂不允许报名参加活动");
				return;
			}
			if (!config.configAdminCheckOnJoin && (p.hasPermission("eventmanager.admin") || p.isOp())){
	    		MessageManager.sendNormalMessage(p, "&c无法以管理员身份加入活动");
	    		return;
	    	}
			if (regPlayers.containsKey(p)) {
				MessageManager.sendNormalMessage(p, "&c你已经报名参加过了,请不要重复报名参加");
				return;
			}
			regPlayers.put(p, false);
			MessageManager.sendNormalMessageToAll(config.messageJoin.replaceAll("%name%", p.getDisplayName())
					.replaceAll("%event%", getEventName())
					.replaceAll("%count%", String.valueOf(getRegCount())));
			MessageManager.sendNormalMessage(p, "你成功报名参加活动:&c" + getEventName() + "&f,输入&6/em quit&f可退出活动");
		}
	}

}
